package net.maku.system.log;

import com.alibaba.fastjson.JSON;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import net.maku.framework.common.utils.HttpContextUtils;
import net.maku.framework.common.utils.IpUtils;
import net.maku.framework.security.user.SecurityUser;
import net.maku.framework.security.user.UserDetail;
import net.maku.system.entity.OperationLogEntity;
import net.maku.system.service.OperationLogService;
import org.apache.commons.collections4.MapUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @date 2023/3/6 16:18
 * @version 1.0
 * @description: 操作日志切面处理类
 */
@Slf4j
@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private OperationLogService operationLogService;

    /**
     * 设置操作日志切入点   在注解的位置切入代码
     */
    @Pointcut("execution(* net.maku.controller.*.*(..))")
    public void oprLogPointCut() {
    }


    /**
     * 记录操作日志
     * @param joinPoint 方法的执行点
     * @param result  方法返回值
     * @throws Throwable
     */

    @AfterReturning(returning  = "result", value = "oprLogPointCut()")
    public void saveOperLog(JoinPoint joinPoint, Object result){
        try{
            Object[] args = joinPoint.getArgs();
            String requestContent = null;
            if (args != null && args.length != 0){
                List<Object> requestList = new ArrayList<>();
                for (Object arg : args){
                    if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse){
                        continue;
                    }
                    requestList.add(arg);
                }
                requestContent = JSON.toJSONString(requestList);
            }
            //将返回值转换成map集合
            UserAgent userAgent = UserAgent.parseUserAgentString(HttpContextUtils.getHttpServletRequest().getHeader("User-Agent"));
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            // 获取用户信息
            UserDetail user = SecurityUser.getUser();
            // 用户ID,"-1" 代表没有登陆系统用户
            Long userId = -1L;
            String userName = "未登陆用户";
            if (!ObjectUtils.isEmpty(user)){
                userId = user.getId();
                userName = user.getUsername();
            }
            // 获取Ip地址
            String ipAddress = IpUtils.getIpAddress();
            OperationLogEntity oprLog = new OperationLogEntity();
            oprLog.setIp(ipAddress);
            oprLog.setBrowser(browser);
            oprLog.setOperatorId(userId);
            oprLog.setOperatorName(userName);
            oprLog.setRequestUri(HttpContextUtils.getHttpServletRequest().getRequestURI());
            oprLog.setRequestContent(requestContent);
            if (result != null){
                String resultStr = JSON.toJSONString(result);
                oprLog.setResponseContent(resultStr);
            }
            oprLog.setCreateTime(new Date());
            operationLogService.save(oprLog);
        }catch (Exception e){
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", e.getMessage());
        }
    }
}
